1. 背景与痛点 (Situation & Task)
在项目(Zhanzhan)初期,为了追求业务的快速迭代,我们采用了传统的 Flutter 单体工程(Monolith)架构。所有的业务逻辑、网络请求、UI 组件和路由都高度集中在同一个 lib 目录下。
随着业务场景的不断丰富(涵盖了“办展”、“看展笔记”、“信息流”、“个人中心”等多个核心域),单体架构的弊端开始集中爆发,主要体现在:
代码边界模糊,陷入“面条代码”: 业务模块之间直接互相
import页面类,导致严重的隐式耦合。改动“商城”模块的代码,可能会意外引发“看展”模块的崩溃。依赖冲突频发,包管理失控: 全局共用一个
pubspec.yaml,第三方依赖版本牵一发而动全身,极大地限制了不同业务线的技术选型自由度。编译与代码生成效率低下: 在单体架构下,运行一次
build_runner生成代码需要遍历全局,耗时极长,严重影响研发心智和效率。
为了支撑中大型团队的协同开发,抹平不同业务模块的进度差,我们决定彻底打破单体架构,全面向 基于 Melos 的 Monorepo(单体仓库多包管理)架构 演进。
2. 核心架构设计:严谨的“四层洋葱模型” (Action - Architecture)
重构的核心不在于拆分物理文件夹,而在于建立清晰的依赖单向传递规则。我们彻底摒弃了按业务粗粒度划分的思路,而是结合业务现状,采用“细粒度拆分 + 严格分层”的设计,将系统划分为四个独立的生命周期层:
2.1 壳工程层 (Host App: apps/host_app)
定位: 整个 App 的组装流水线。
职责: 自身几乎不包含具体的业务逻辑代码(除了
splash启动页等强入口逻辑)。它负责引入底层和业务侧的各个 package,完成全局路由表 (app_routes.dart) 的注册、状态管理 (ProviderScope) 的初始化,以及全局依赖注入。
2.2 基础能力层 (Core: packages/core)
定位: 极度稳定、与业务毫无关联的底层基建。
模块:
core_network: 基于 Dio 的网络封装、拦截器体系与 Mock 机制。core_router: 基于 GoRouter 的全局路由抽象。core_storage: 本地持久化(Token 管理)。core_analytics: 全局埋点服务。
2.3 公共复用层 (Common: packages/common)
定位: 跨业务模块复用的中间件与共享领域。
模块:
auth_session: 用户鉴权守卫与当前用户信息。design_system: 统一的设计语言(UI 组件、颜色、字体)。shared_models: 跨模块的高频实体(如 ExhibitRepository,保证数据一致性)。
2.4 业务功能层 (Features: packages/features)
定位: 并行迭代的业务线,高度内聚。
模块:
feature_auth(登录)、feature_home(首页)、feature_exhibit(办展)、feature_note(笔记)。铁律: 各 feature 包之间绝对物理隔离,禁止相互依赖。跨业务通信统一上浮至壳工程的路由中心或通过协议解耦。
3. 关键技术决策 (Action - Key Decisions)
在此次重构落地过程中,我们做出了几个对后续研发规范具有决定性意义的技术决策:
决策一:采用微模块(Micro-feature)而非宏观领域驱动
在模块划分初期,我们曾面临是建立宏观的“商城”和“看展”大包,还是按实际功能拆分的抉择。考虑到团队规模和业务敏捷度,我们最终选择了以现状为准的细粒度拆分。
我们没有预先建立空壳的“业务大组”,而是将 exhibit、note 等功能抽离为独立的 feature。同时,将 auth 这种具有跨域性质的模块下沉,将 splash 等应用生命周期强相关的代码保留在壳工程。这种实事求是的拆解,避免了过度设计,也使得架构不会头重脚轻。
决策二:确立严苛的 Import 路径规范
为了防止 Monorepo 再次退化为单体,我们在代码静态检查中贯彻了基于物理隔离的引用原则:
包内高内聚(自闭环): 同一个 package 内部(例如
feature_auth内部)互相调用,强制使用相对路径../。这保证了模块的完全可移植性。包间低耦合(物理边界): 跨越 package 借用能力时,严禁使用
../。必须在pubspec.yaml中声明依赖后,使用package:绝对路径引入。这为代码审查(Code Review)提供了最直观的边界预警。
决策三:Riverpod 状态与路由的分布式管理
得益于架构分层,我们对状态管理也进行了重组。底层的网络和存储服务在 core 中以 Provider 提供;业务数据层(如 homeNoteRepository)集中在 shared_models 中以便跨域调用;而页面 UI 的状态(如 LoginController, HomeFeedController)则通过 @riverpod 局部封闭在各自的 feature 包内。配合 Melos 的并行脚本,极大地提升了代码生成的效率。
4. 落地收益与未来展望 (Result)
经过数周的奋战,Zhanzhan 项目已全面平稳过渡到 Monorepo 架构。带来的直接收益包括:
研发效能跃升: 开发“办展”模块的同学只需关注
feature_exhibit,无需关心“笔记”模块的代码变更。同时melos run build的并行代码生成,将原本漫长的等待时间缩短了 70% 以上。强制的防腐层建设: feature 之间的硬隔离,彻底杜绝了业务间的循环依赖,使代码架构符合开闭原则(OCP)。
技术栈解绑: 独立的
pubspec.yaml使得各个模块在未来可以独立升级依赖库,甚至在核心能力层进行灰度技术替换而不影响上层业务。
展望:
随着这套基础设施的落成,我们下一步的重心将转向模块的独立编译与调试。依托 Melos 的能力,我们将为每个核心 Feature 构建独立的 example 工程,使得研发人员在不运行完整壳工程的情况下,也能快速启动并调试单一模块,真正实现从“能跑”向“跑得快”的敏捷研发转型。
项目:
zhanzhan(Flutter + Riverpod + Dio · Melos Monorepo)
1. 根目录概览
1 | zhanzhan/ |
2. Monorepo 子包总览
| 层级 | 包路径 | name | 说明 |
|---|---|---|---|
| 壳工程 | apps/host_app | zhanzhan | 主入口、路由注册、平台工程 |
| 基础层 | packages/core/core_network | core_network | Dio 实例、拦截器、Mock |
| 基础层 | packages/core/core_storage | core_storage | Token 持久化(SharedPreferences) |
| 基础层 | packages/core/core_router | core_router | GoRouter 抽象、全局导航 |
| 基础层 | packages/core/core_analytics | core_analytics | Matomo 埋点服务 |
| 公共层 | packages/common/auth_session | auth_session | 鉴权守卫、当前用户服务 |
| 公共层 | packages/common/design_system | design_system | 主题颜色/字体/间距 + 通用 UI 组件 |
| 公共层 | packages/common/shared_models | shared_models | 跨模块共享的模型与 Repository |
| 功能层 | packages/features/feature_auth | feature_auth | 登录/协议 |
| 功能层 | packages/features/feature_home | feature_home | 首页 |
| 功能层 | packages/features/feature_exhibit | feature_exhibit | 办展 |
| 功能层 | packages/features/feature_note | feature_note | 笔记 |
| 功能层 | packages/features/feature_splash | feature_splash | 启动页 |
3. 壳工程(apps/host_app)
壳工程负责组装各个包,提供应用入口和路由注册。
1 | apps/host_app/lib/ |
4. 基础能力层(packages/core)
4.1 core_network(网络层)
1 | packages/core/core_network/lib/ |
4.2 core_storage(本地存储)
1 | packages/core/core_storage/lib/ |
4.3 core_router(路由抽象)
1 | packages/core/core_router/lib/ |
4.4 core_analytics(埋点)
1 | packages/core/core_analytics/lib/ |
5. 公共复用层(packages/common)
5.1 auth_session(鉴权会话)
1 | packages/common/auth_session/lib/ |
5.2 design_system(设计系统)
1 | packages/common/design_system/lib/ |
5.3 shared_models(共享模型)
1 | packages/common/shared_models/lib/ |
6. 业务功能模块(packages/features)
6.1 feature_auth(登录/注册/协议)
1 | packages/features/feature_auth/lib/ |
6.2 feature_home(首页)
1 | packages/features/feature_home/lib/ |
6.3 feature_exhibit(办展)
1 | packages/features/feature_exhibit/lib/ |
6.4 feature_note(笔记)
1 | packages/features/feature_note/lib/ |
6.5 feature_splash(启动页)
1 | packages/features/feature_splash/lib/ |
7. 数据接口与 Repository 映射
详细接口原始文档见:
docs/api.md。
7.1 鉴权/用户相关
AuthRepository(feature_auth)GET /sms/amaz/wxapp/send_sms(发送验证码)POST /sms/amaz/wxapp/verify_sms(验证码登录)
AgreementRepository(feature_auth)GET /user/sys/agreement/get(协议内容)
CurrentUserService(auth_session)GET /user/amaz/user/info(用户信息)POST /user/amaz/user/update(更新资料)
7.2 办展相关
ExhibitRepository(shared_models)- 分类:
/api/exhibition/category/list、/api/exhibition/category/tree - 音乐:
/api/music/system/normal - 展览列表/详情:
/api/exhibition/list、/api/exhibition/{id} - 展览流:
/api/information/exhibition/get - 互动聊天:
/api/exhibition/interact/chat/list、/api/exhibition/interact/chat/add - 评论:
/api/exhibition/comment/list、/api/exhibition/comment/add、/api/exhibition/interact/comment/delete - 模板:
/api/exhibition/hall/template/{templateId}、/api/exhibition/hall/template/page - 发布:
/api/exhibition/saveOrUpdate
- 分类:
7.3 首页/笔记相关
HomeNoteRepository(shared_models)- 信息流:
/api/information/follow/get - 笔记列表:
/api/information/note/get - 点赞列表:
/api/note/take/home/like/list - 评论列表:
/api/note/take/home/list - 详情:
/api/note/take/detail - 创建/编辑:
/api/note/edit/create_modify
- 信息流:
NoteCommentRepository(feature_note)- 评论列表:
/api/note/take/list - 评论新增:
/api/note/take/add
- 评论列表:
NoteInteractionRepository(shared_models)- 关注:
/user/amaz/user/add、/user/amaz/user/cancel - 点赞/收藏:
/user/like/divide/add、/user/like/divide/cancel
- 关注:
8. Provider 与状态管理分布
- 全局网络与服务:
dioProvider(core_network)tokenStorageServiceProvider(core_storage)currentUserServiceProvider(auth_session)authErrorHandlerProvider(core_network,壳工程注入实现)
- 功能 Repository Provider:
authRepositoryProvider(feature_auth)agreementRepositoryProvider(feature_auth)exhibitRepositoryProvider(shared_models)homeNoteRepositoryProvider(shared_models)noteCommentRepositoryProvider(feature_note)noteInteractionRepositoryProvider(shared_models)
- 控制器(
@riverpod/ Notifier):LoginController(feature_auth)ExhibitTabController(feature_exhibit)HomeFeedController(feature_home)HomeVideoController(feature_home)HomeVideoInteractionController(feature_home)NoteDetailController(feature_note)NoteCommentController(feature_note)NoteInteractionController(feature_note)